/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package view;

import java.awt.*;
import java.awt.font.TextAttribute;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.tree.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

/**
 * Cette classe hérite la classe JPanel qui comporte des éléments communs
 * des briques des types Répartition, Liste, Graphe.
 * @author NGUYEN Dac Cong Tai
 */
public abstract class View extends JPanel{
    public static final int thickness = 4;
    protected JScrollPane scrollPane;
    protected Element brique;
    protected Element parametre;
    protected String codeLangue;
    protected String typeProfil;
    protected ArrayList<Boolean> typeOperations; // moyenne = false / somme = true
    protected ArrayList<JComboBox> listComboBox;
    protected ArrayList<JMenu> listMenuVal;

    /**
     * Constructeur d'un objet View
     * @param brique l'élément contient des informations de la brique
     * @param ecran la dimension de l'écran actuel
     * @param element l'élément contient les textes pour cette brique
     * @param langue le code de la langue d'affichage
     * @param typeProfil le texte indique le type du profil (profil d'élèves ou profil de groupe)
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    public View(Element brique, Dimension ecran, Element element, String langue, String typeProfil) throws ParserConfigurationException, SAXException, IOException{
        this.brique = brique;
        parametre = element;
        codeLangue = langue;
        this.typeProfil = typeProfil;
        setLayout(new BorderLayout());
    }

    /**
     * Renvoie la police pour le contenu dont ses attributs sont récupérés à partir du fichier de configuration "Preferences.xml".
     * @return la police pour le contenu
     * @throws UnsupportedEncodingException
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    public static Font getContent() throws UnsupportedEncodingException, ParserConfigurationException, SAXException, IOException {
        Element rootEl = perl.Utility.getElement(perl.Utility.getPath(View.class, "/Fichiers systeme/Parametres/Preferences.xml"));
        Element policeParDefault = (Element) ((Element)rootEl.getElementsByTagName("Police").item(0)).getElementsByTagName("PoliceParDefaut").item(0);
        String nom = policeParDefault.getElementsByTagName("nom").item(0).getTextContent();
        String style = policeParDefault.getElementsByTagName("style").item(0).getTextContent();
        String taille = policeParDefault.getElementsByTagName("taille").item(0).getTextContent();
        Font font = new Font(nom, Font.PLAIN, Integer.parseInt(taille));
        Map map = font.getAttributes();
        if (style.contains("Souligne") ){
            map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
        }else if (style.contains("Gras")){
            map.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
        } else if (style.contains("Italique")){
            map.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
        }else if (style.contains("Barre")){
             //map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
            //map.put(TextAttribute.INPUT_METHOD_UNDERLINE, TextAttribute.UNDERLINE_LOW_DOTTED);
            //return new Font(nom, Font.ITALIC, Integer.parseInt(taille));
        }
        return new Font(map);
    }

    /**
     * Renvoie la police pour les titres dont son nom est Kristen ITC, et sa taille est 15.
     * @return la police pour les titres
     */
    public static Font getTitle() {
        return new Font("Kristen ITC", Font.BOLD, 15);
    }

    /**
     * Récupère les commentaires d'une brique, ou d'un composante, ou d'un sous-composante puis y ajoute.
     * @param commentaire l'élément contient des informations de la commentaire
     * @param composante le composante contient cette commentaire
     * @param vues l'élément contient les textes pour cette commentaire
     * @param langue le code de la langue d'affichage
     */
    public static void getCommentaire(Element commentaire, DefaultMutableTreeNode composante, Element vues, String langue){
        NodeList listEvaluations = commentaire.getElementsByTagName("commentaire");
        //System.out.println("evaluation: "+listEvaluations.getLength());
        if (listEvaluations.getLength()!=0){
            DefaultMutableTreeNode comment = new DefaultMutableTreeNode(((Element)vues.getElementsByTagName("Commentaires").item(0)).getElementsByTagName(langue).item(0).getTextContent());
            for (int i=0; i<listEvaluations.getLength(); i++){
                Element evaluation = (Element) listEvaluations.item(i);
                String date = evaluation.getAttribute("date");
                String source = evaluation.getAttribute("source");
                String texte = evaluation.getTextContent();
                String str="";
                if(!date.equals("")){
                    str+=date+" : ";
                }
                if(!source.equals("")){
                    str+="[ "+source+" ] : ";
                }
                if(!texte.equals("")){
                    str+=texte;
                }
                if(!str.equals("")){
                    DefaultMutableTreeNode eval = new DefaultMutableTreeNode(str,true);
                    comment.add(eval);
                }
                //DefaultMutableTreeNode eval = new DefaultMutableTreeNode(date+": "+source+": "+texte);
                //comment.add(eval);
            }
            if(!comment.isLeaf())
                composante.add(comment);
        }
    }

    /**
     * Récupère les évalusations de valeur d'une brique, ou d'un composante, ou d'un sous-composante puis y ajoute.
     * @param valeur l'élément contient des informations de la valeur
     * @param type le texte indique le type de la valeur (c.à.d son identifiant dans l'échelle des valeurs)
     * @param composante le composante contient cette valeur
     * @param typeOperation une liste des booléens définit les types d'opération des valeurs (false = moyenne / true = somme)
     * @param indexVal l'ordre de cette valeur (ex: valeur 1 ou valuer 2)
     * @param typeProfil le texte indique le type du profil (élèves ou groupe)
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    public void getEvaluation(Element valeur, String type, DefaultMutableTreeNode composante, ArrayList<Boolean> typeOperation, int indexVal, String typeProfil) throws ParserConfigurationException, SAXException, IOException{
        NodeList listEvaluations = valeur.getElementsByTagName("evaluation");
        if (listEvaluations.getLength()!=0){
            ArrayList<String> listValues = new ArrayList<String>();
            for (int i=0; i<listEvaluations.getLength(); i++){
                Element evaluation = (Element) listEvaluations.item(i);
                String date = evaluation.getAttribute("date");
                String source = evaluation.getAttribute("source");
                String texte = evaluation.getTextContent();
                String str="";
                if(!date.equals("") && !texte.equals("")){
                    str+=date+" : ";
                }
                if(!source.equals("")){
                    str+="[ "+source+" ] : ";
                }
                if(!texte.equals("")){
                    str+=texte;
                    listValues.add(texte);
                }
                if(!str.equals("")){
                    DefaultMutableTreeNode eval = new DefaultMutableTreeNode(str,true);
                    composante.add(eval);
                }

            }
            if(type!= null && !type.equals("")){
               
                    String moyenne = operation(listValues, Integer.parseInt(type), typeOperation.get(indexVal), typeProfil);
                    //listComboBox.get(indexVal).setEnabled(false);
                    if(moyenne!=null){
                        if(typeOperation.size()>0){
                            String tmp = composante.getUserObject().toString();
                            composante.setUserObject(tmp+"  ("+(indexVal+1)+": "+moyenne+")");
                        }else {
                            String tmp = composante.getUserObject().toString();
                            composante.setUserObject(tmp+"  ("+moyenne+")");
                        }
                    }
               
            }
        }
    }

    /**
     * Traite des éléments qui sont des composantes.
     * @param composante le noeud contient des informations du composante
     * @param vues l'élément contient les textes pour ce composante
     * @param langue le code de la langue d'affichage
     * @param typeOperation une liste des booléens définit les types d'opération des valeurs (false = moyenne / true = somme)
     * @param typeProfil le texte indique le type du profil (apprenant ou groupe)
     * @return un arbre d'exploitation de type DefaultMutableTreeNode contient des informations de ce composante
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    private DefaultMutableTreeNode traiterComposante(Node composante, Element vues, String langue, ArrayList<Boolean> typeOperation, String typeProfil) throws ParserConfigurationException, SAXException, IOException {
        String nomComposante = ((Element)composante).getAttribute("nom");

        //String nomComposante = composante.getAttributes().getNamedItem("nom").toString();
        nomComposante = ((Element)vues.getElementsByTagName("Composante").item(0)).getElementsByTagName(langue).item(0).getTextContent()+" \""+nomComposante+"\"";

        DefaultMutableTreeNode nodeComposante = new DefaultMutableTreeNode(nomComposante);
        //System.out.println(nodeComposante.toString());
        Node sousComposante = composante.getFirstChild();
        int index=0;
        int indexVal=0;
        while(index<composante.getChildNodes().getLength()){
        //System.out.println("--<<<"+sousComposant.getNodeName());
            if (sousComposante.getNodeName().equals("commentaires")){
                getCommentaire((Element) sousComposante, nodeComposante, vues, langue);
            }else if (sousComposante.getNodeName().equals("valeur")){
                String type = ((Element)sousComposante).getAttribute("id_echelle");
                //System.out.bleTreeNode value = new DefaultMutableTreeNode("valeur");
                getEvaluation((Element) sousComposante, type, nodeComposante, typeOperation, indexVal, typeProfil);
                indexVal++;
            } else if(sousComposante.getNodeName().equals("sous_composante")){
                DefaultMutableTreeNode nodeSousComposante = traiterSousComposante((Element) sousComposante, vues, langue, typeOperation, typeProfil);
                nodeComposante.add(nodeSousComposante);
            }
            sousComposante = sousComposante.getNextSibling();
            index++;
        }
        return nodeComposante;
    }

    /**
     * Traite des éléments qui sont des sous-composantes.
     * @param sousComposante l'élément contient des informations du sous-composante
     * @param vues l'élément contient les textes pour ce sous-composante
     * @param langue le code de la langue d'affichage
     * @param typeOperation une liste des booléens définit les types d'opération des valeurs (false = moyenne / true = somme)
     * @param typeProfil le texte indique le type du profil (apprenant ou groupe)
     * @return un arbre d'exploitation de type DefaultMutableTreeNode contient des informations de ce sous-composante
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    private DefaultMutableTreeNode traiterSousComposante(Element sousComposante, Element vues, String langue, ArrayList<Boolean> typeOperation, String typeProfil) throws ParserConfigurationException, SAXException, IOException{
        String nomSousComposante = ((Element)vues.getElementsByTagName("SousComposante").item(0)).getElementsByTagName(langue).item(0).getTextContent()+" : "+sousComposante.getAttribute("nom");
        DefaultMutableTreeNode nodeSousComposante = new DefaultMutableTreeNode(nomSousComposante);
        //if(sousComposante.getElementsByTagName("sous_composante").getLength()==0){
        Node tempo = sousComposante.getFirstChild();
        int index=0;
        int indexVal=0;
        //System.out.println(nomSousComposante+": "+sousComposante.getChildNodes().getLength());
        while(index<sousComposante.getChildNodes().getLength()){
            //System.out.println("    "+tempo.getNodeName());
            if (tempo.getNodeName().equals("commentaires")){
                getCommentaire((Element) tempo, nodeSousComposante, vues, langue);
            }else if (tempo.getNodeName().equals("valeur")){
                String type = ((Element)tempo).getAttribute("id_echelle");
                getEvaluation((Element) tempo, type, nodeSousComposante, typeOperation, indexVal, typeProfil);
                indexVal++;
            } else if (tempo.getNodeName().equals("sous_composante")){
                DefaultMutableTreeNode nodeTmp = traiterSousComposante((Element)tempo, vues, langue, typeOperation, typeProfil);
                nodeSousComposante.add(nodeTmp);
            }
            tempo = tempo.getNextSibling();
            index++;
        }

        return nodeSousComposante;
    }

    /**
     * Crée un arbre d'exploitation d'une brique.
     * @param brique l'élément contient des informations de la brique
     * @param vues l'élément contient les textes pour ce composante
     * @param langue le code de la langue d'affichage
     * @param typeOperation une liste des booléens définit les types d'opération des valeurs (false = moyenne / true = somme)
     * @param typeProfil le texte indique le type du profil (apprenant ou groupe)
     * @return un arbre d'exploitation de type JTree contient des informations de cette brique
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    public JTree createTree(Element brique, Element vues, String langue, ArrayList<Boolean> typeOperation, String typeProfil) throws ParserConfigurationException, SAXException, IOException{
        Node element = brique.getFirstChild();
        DefaultMutableTreeNode tree = new DefaultMutableTreeNode(brique.getAttribute("nom"),true);
        //System.out.println(brique.getChildNodes().getLength());
        int index=0;
        while(index<brique.getChildNodes().getLength()){
            //System.out.println(element.getNodeName());
            if (element.getNodeName().equals("commentaires")){
                getCommentaire((Element) element, tree, vues, langue);
            }else if (element.getNodeName().equals("arbre_des_composantes")){
                NodeList listArbreDesComposantes = brique.getElementsByTagName("arbre_des_composantes");
                //System.out.println("arbre des compos: "+listArbreDesComposantes.getLength());
                for (int i=0; i<listArbreDesComposantes.getLength();i++){
                    //Recuperer l'arbre des composantes
                    Element arbreComposante = (Element) listArbreDesComposantes.item(i);


                    // Recuperer la liste des composantes
                    NodeList listComposantes = arbreComposante.getElementsByTagName("composante");
                    //System.out.println("des compos: "+listComposantes.getLength());
                    for (int j=0; j<listComposantes.getLength(); j++){

                        //Element composant = (Element) listComposant.item(j);
                        Node composant = listComposantes.item(j);

                        DefaultMutableTreeNode tmp = traiterComposante(composant, vues, langue, typeOperation, typeProfil);
                        
                        tree.add(tmp);
                    }
                }
            }
            //System.out.println(element.getNodeName());
            element = element.getNextSibling();
            index++;
        }

        return convertToJTree(tree);
    }

    /**
     * Convertit un DefaultMutableTreeNode en un arbre JTree.
     * @param node le DefaultMutableTreeNode
     * @return l'arbre JTree
     */
    public JTree convertToJTree(DefaultMutableTreeNode node){
        JTree result = new JTree(node);
        try {
            result.setFont(getContent());
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex);
        }

        result.setUI(new BasicTreeUI(){
            @Override
            protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds, TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf){ }
            @Override
            protected void paintVerticalPartOfLeg(Graphics g, Rectangle clipBounds, Insets insets, TreePath path){ }
        });

        ((BasicTreeUI) result.getUI()).setExpandedIcon(null);
        ((BasicTreeUI) result.getUI()).setCollapsedIcon(null);

        
        ImageIcon leafIcon = new ImageIcon(perl.App.class.getResource("resources/crayon.png"));
        ImageIcon closeIcon = new ImageIcon(perl.App.class.getResource("resources/minus.png"));
        ImageIcon openIcon = new ImageIcon(perl.App.class.getResource("resources/add.png"));
        if (leafIcon != null) {
            DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
            renderer.setLeafIcon(leafIcon);
            renderer.setClosedIcon(openIcon);
            renderer.setOpenIcon(closeIcon);
            result.setCellRenderer(renderer);
        } else {
            System.err.println("Leaf icon missing; using default.");
        }

        result.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        result.setRootVisible(false);
        //result.addTreeExpansionListener(this);
        deployerArbre(result);
        return result;
    }

    /**
     * Déploie un arbre JTree.
     * @param tree l'arbre
     */
    public static void deployerArbre(JTree tree){
        for (int i=0; i<tree.getRowCount(); i++){
            tree.expandRow(i);
        }
    }

    /**
     * Revoie une couleur à partir d'un texte de couleur en delphi en appelant la fonction "getHexaColor".
     * (en java est RGB - en Delphi est BGR)
     * @param nodeList la liste des éléments contient des informations des briques
     * @param type le texte indique le type du brique (0=type Liste, 1=type Répartition, 2=type Graphe, 3=type Texte)
     * @return la couleur
     */
    public static Color decodeColor(NodeList nodeList, String type){
        String hexa = getHexaColor(nodeList, type);
        if (hexa!=null && hexa.startsWith("$")){
            String B = hexa.substring(3, 5);
            String G = hexa.substring(5, 7);
            String R = hexa.substring(7, 9);
            //System.out.println(R+" / "+G+" / "+B);
            return new Color(Integer.parseInt(R+G+B, 16));
        } else {
            System.err.println("Color inconnu; using default.");
            return Color.black;
        }
    }

    /**
     * Renvoie une couleur pour les titres à partir de la couleur de la brique.
     * @param color la couleur de la brique
     * @return  renvoie le blanc si la couleur de la brique est foncée
     *          renvoie le noir sinon
     */
    public static Color getTextColor(Color color){
        if(color!=null){
            int B = color.getBlue();
            int G = color.getGreen();
            int R = color.getRed();
            //System.out.println(R+" / "+G+" / "+B);
            if(R<10 || G<10 || B<10 || (R<=63 && G<=63 && B<=63)
                || (Math.abs(R-B)<=20 && Math.abs(R-G)<=20 && Math.abs(B-G)<=20)
                || (Math.abs(R-B)<=20 && Math.abs(R-G)<=63) || (Math.abs(R-G)<=20 && Math.abs(R-B)<=63) || (Math.abs(B-G)<=20 && Math.abs(B-R)<=63)){
                return Color.white;
            } else {
                return Color.black;
            }
        }else{
            System.err.println("Color inconnu; using default.");
            return Color.black;
        }
    }

    /**
     * Renvoie la couleur en delphi d'une brique
     * @param nodeList la liste des éléments contient des informations des briques
     * @param type le texte indique le type du brique (0=type Liste, 1=type Répartition, 2=type Graphe, 3=type Texte)
     * @return le texte de couleur en delphi
     */
    private static String getHexaColor(NodeList nodeList, String type){
        for (int i=0; i<nodeList.getLength(); i++){
            if (((Element)nodeList.item(i)).getAttribute("id").equals(type)){
                return ((Element)nodeList.item(i)).getAttribute("couleur");
            }
        }
        return null;
    }

    /**
     * Fait des opérations sur les evaluations.
     * @param listValues une liste des valeurs des évaluations
     * @param type le type de valeur
     * @param typeOperation le booléen définit le type d'opération (false = moyenne / true = somme)
     * @param typeProfil le texte indique le type du profil (apprenant ou groupe) (à servir dans l'avenir)
     * @return le texte indique le résultat de l'opération
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    private String operation(ArrayList<String> listValues, int type, boolean typeOperation, String typeProfil) throws ParserConfigurationException, SAXException, IOException{
        Element critere = getCritere(type);
        if(critere!=null){
            if(critere.getElementsByTagName("numerique").getLength()>0){
                Double sum=0.0;
                for (int i=0; i<listValues.size(); i++){
                    sum+=Double.parseDouble(listValues.get(i).replace(",", "."));
                }
                if(typeOperation){
                    return sum.toString();
                } else {
                    DecimalFormat df = new DecimalFormat ( ) ;
                    df.setMaximumFractionDigits ( 2 ) ;
                    return df.format(sum/listValues.size());
                }
            } else if(critere.getElementsByTagName("textuel").getLength()>0){
                /*if(typeProfil.equals("Eleve")){
                    if(typeOperation){
                        ArrayList values = new ArrayList();
                        ArrayList<Integer> numbersOfValue = new ArrayList<Integer>();
                        for (int i=0; i<listValues.size(); i++){
                            if(!values.contains(listValues.get(i))){
                                values.add(listValues.get(i));
                                numbersOfValue.add(1);
                            } else {
                                int index = values.indexOf(listValues.get(i));
                                int number = numbersOfValue.get(index);
                                number++;
                                numbersOfValue.set(index, number);
                            }
                        }
                        String str="";
                        for (int j=0; j<values.size()-1; j++){
                            str+= numbersOfValue.get(j)+" "+values.get(j)+", ";
                        }
                        str+= numbersOfValue.get(values.size()-1)+" "+values.get(values.size()-1);
                        return str;
                    } else {
                        Element textuel = (Element)critere.getElementsByTagName("textuel").item(0);
                        if (textuel.getAttribute("gradue").equals("oui")){
                            Double sum=0.0;
                            for (int i=0; i<listValues.size(); i++){
                                sum+=convert2double(critere,listValues.get(i));
                            }
                            return convert2string(critere, sum/listValues.size());
                        } else
                            return null;
                    }
                } else if (typeProfil.equals("Groupe")){*/
                    if(typeOperation){
                        ArrayList values = new ArrayList();
                        ArrayList<Integer> numbersOfValue = new ArrayList<Integer>();
                        if(convert2double(critere, listValues.get(0))==null){
                            for (int i=0; i<listValues.size(); i++){
                                String[] split = listValues.get(i).split("; ");
                                for (int j=0; j<split.length; j++){
                                    String str = split[j];
                                    int number = Integer.parseInt(str.substring(0, str.indexOf(" ")));
                                    String text = str.substring(str.indexOf(" ")+1, str.length());
                                    if(!values.contains(text)){
                                        values.add(text);
                                        numbersOfValue.add(number);
                                    } else {
                                        int index = values.indexOf(text);
                                        int numberOfText = numbersOfValue.get(index);
                                        numberOfText+=number;
                                        numbersOfValue.set(index, numberOfText);
                                    }
                                }
                            }
                        } else {
                            for (int i=0; i<listValues.size(); i++){
                                if(!values.contains(listValues.get(i))){
                                    values.add(listValues.get(i));
                                    numbersOfValue.add(1);
                                } else {
                                    int index = values.indexOf(listValues.get(i));
                                    int number = numbersOfValue.get(index);
                                    number++;
                                    numbersOfValue.set(index, number);
                                }
                            }
                        }
                        String str="";
                        for (int j=0; j<values.size()-1; j++){
                            str+= numbersOfValue.get(j)+" "+values.get(j)+"; ";
                        }
                        str+= numbersOfValue.get(values.size()-1)+" "+values.get(values.size()-1);
                        return str;
                    } else{
                        Element textuel = (Element)critere.getElementsByTagName("textuel").item(0);
                        if (textuel.getAttribute("gradue").equals("oui")){



                            Double sum=0.0;
                            if(convert2double(critere, listValues.get(0))==null){
                                int sumText=0;
                                for (int i=0; i<listValues.size(); i++){
                                    String[] split = listValues.get(i).split("; ");
                                    for (int j=0; j<split.length; j++){
                                        String str = split[j];
                                        int number = Integer.parseInt(str.substring(0, str.indexOf(" ")));
                                        sumText+=number;
                                        String text = str.substring(str.indexOf(" ")+1, str.length());
                                        sum+=(number*convert2double(critere,text));
                                    }
                                }
                                return convert2string(critere, sum/sumText);
                            }else {
                                for (int i=0; i<listValues.size(); i++){
                                    sum+=convert2double(critere,listValues.get(i));
                                }
                                return convert2string(critere, sum/listValues.size());
                            }
                        } else
                            return null;
                    }
                /*} else
                    return null;*/
            } else
                return null;
        } else
            return null;

    }

    /**
     * Converti un texte en un nombre sous la forme :
     * la dernière valeur de ce type est égale à 1, puis on augmente 1 pour la précédente jusqu’à la première.
     * @param critere l'élément contient des informations d'une type de valeur
     * @param str le texte
     * @return un Double
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    private Double convert2double(Element critere, String str) throws ParserConfigurationException, SAXException, IOException{
        Node textuel = critere.getElementsByTagName("textuel").item(0);
        Node value = textuel.getLastChild();
        Double result = 0.0;
        int index=0;
        while (index<textuel.getChildNodes().getLength()){
            if (value.getNodeName().equals("val")){
                result += 1.0;
                if (value.getTextContent().equals(str))
                    return result;
            }
            value = value.getPreviousSibling();
            index++;
        }
        return null;
    }

    /**
     * Converti un nombre en un texte.
     * Exemple : Une type a 2 valeurs : acquis et non acquis.
     * La valeur d’une composante est 2 acquis et 1 non acquis. Non acquis = 1, et acquis = 2.
     * Après le converti, on reçoit la moyenne (1+2x2)/3=1,67. Cette moyenne correspond à acquis
     * (c.à.d. si 0<=la moyenne<1,5 alors c’est non acquis, si la moyenne >=1,5 alors c’est acquis).
     * @param critere l'élément contient des informations d'une type de valeur
     * @param d le nombre
     * @return un texte
     */
    private String convert2string(Element critere, Double d){
        Node textuel = critere.getElementsByTagName("textuel").item(0);
        Node value = textuel.getLastChild();
        int index=0;
        int indexVal=0;
        while (index<textuel.getChildNodes().getLength()){
            if (value.getNodeName().equals("val")){
                if (indexVal==0){
                    d = d-1.5;
                } else {
                    d = d-1.0;
                }
                //System.out.println(d+": "+value.getTextContent());
                if(d<0){
                    return value.getTextContent();
                }
                indexVal++;
            }
            value = value.getPreviousSibling();
            index++;
        }
        return null;
    }

    /**
     * Renvoie un élément qui contient des informations sur une type de valeurs dans le fichier "echelle.xml"
     * correspondant à un identifiant donné.
     * @param type l'identifiant
     * @return l'élément qui contient des informations sur une type de valeurs
     * @throws UnsupportedEncodingException
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    private Element getCritere(int type) throws UnsupportedEncodingException, ParserConfigurationException, SAXException, IOException{
        Element rootEl = perl.Utility.getElement(perl.Utility.getPath(View.class, "/Fichiers systeme/Parametres/echelle.xml"));
        NodeList listCriteres = rootEl.getElementsByTagName("critere");
        for (int i=0; i<listCriteres.getLength();i++){
            if (Integer.parseInt(((Element)listCriteres.item(i)).getAttribute("id").toString())==type){
                return (Element)listCriteres.item(i);
            }
        }
        return null;
    }

    /**
     * Renvoie la liste des booléens des opérations.
     * S'il est faux, c'est la moyenne, s'il est vrai, c'est la somme
     * @return la liste des booléens
     */
    public ArrayList<Boolean> getTypeOperations() {
        return typeOperations;
    }

    /**
     * Renvoie la liste des menus des briques.
     * @return la liste des menus des briques
     */
    public ArrayList<JMenu> getListMenuVal() {
        return listMenuVal;
    }
}
